package com.totalinlink.dsl.poi.wrappers
import com.totalinlink.dsl.poi.WorkBookBuilder
import org.apache.poi.xssf.usermodel.XSSFWorkbook
/**
 * Created by wangguangyu on 15/5/24.
 */
class WorkBookWrapper extends NodeWrapper {

    static CLS_MAPS = [:]

    static {

        // for add a sheet to workbook
        CLS_MAPS[SheetWrapper.class] = {workbook, sheet ->
            sheet.index = workbook.sheets.size()
            workbook.sheets << sheet
        }
        // for add a named style to workbook
        CLS_MAPS[CellStyleWrapper.class] = {workbook, style ->
            workbook.namedStyles[style.name] = style
        }
        // for add a named font to workbook
        CLS_MAPS[FontWrapper.class] = {workbook, font ->
            workbook.namedFonts[font.name] = font
        }
    }
    // sheets in wrapper
    def sheets = []
    // file name
    def filename
    // named styles
    def namedStyles = [:]
    // named fonts
    def namedFonts = [:]

    /**
     * synchronize the object bind in workbook by certain order
     */
    @Override
    void syncNode() {
        // sync workbook object
        if (!this.poiObject) {
            this.poiObject = new XSSFWorkbook()
        }
        // sync named fonts
        namedFonts.each { k, v ->
            v.syncNode()
        }
        // sync named styles
        namedStyles.each { k, v ->
            v.syncNode()
        }
        // sync sheets of workbook
        sheets.each {
            it.syncNode()
        }
    }

    @Override
    void setNode(child) {
        CLS_MAPS[child.class](this, child)
    }

    def WorkBookWrapper(WorkBookBuilder workBookBuilder, Map attributes) {

        super(workBookBuilder, attributes)

        this.filename = attributes.filename
    }

    def save() {
        assert filename
        def file = new File(filename)

        if (file.exists()) {
            file.delete()
        }

        def outputStream  = new FileOutputStream(filename)
        save(outputStream)

    }

    def save(os) {
        assert os
        try {
            syncNode()
            this.poiObject = this.poiObject ?: new XSSFWorkbook()
            this.poiObject.write(os)
        } catch (IOException e) {
            e.printStackTrace()
        } finally {
            os.close()
        }
    }
}
